package com.cykj.faceledtv.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.cykj.faceledtv.MyApp;
import com.cykj.faceledtv.data.db.model.UserData;
import com.cykj.faceledtv.entity.NettyConstants;
import com.cykj.faceledtv.entity.NettyReceiverModel;
import com.cykj.faceledtv.entity.NettySendMsgModel;
import com.cykj.faceledtv.entity.ResultModel;
import com.cykj.faceledtv.entity.RecordData;
import com.cykj.faceledtv.listener.FaceListener;
import com.cykj.faceledtv.netty.NettyClient;
import com.cykj.faceledtv.netty.NettyListener;
import com.cykj.faceledtv.utils.Base64Utils;
import com.cykj.faceledtv.utils.FileUtils;
import com.cykj.faceledtv.utils.MacUtils;
import com.cykj.faceledtv.utils.Md5Utils;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.orhanobut.logger.Logger;

import org.json.JSONObject;

import java.nio.charset.Charset;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;


/**
 * 处理tcp传递过来的数据
 *
 * @author jzh
 * @date 2019/05/10 10:56
 */
public class FaceLedService extends Service implements NettyListener {
    private MyBinder myBinder = new MyBinder();
    private ExecutorService es;
    private FaceListener listener;
    /**
     * md5加密后的mac
     */
    private String md5Mac;
    private String mac;
    /**
     * 心跳定时线程
     */
    private ScheduledExecutorService pulseEs;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        connect();
        return myBinder;
    }

    public void setFaceListener(FaceListener listener) {
        this.listener = listener;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        destroyThreadPool();
        shutDown();
        NettyClient.getInstance().release();
    }

    private void shutDown() {
        if (es != null && !es.isShutdown()) {
            try {
                es.shutdownNow();
                es = null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 与activity绑定
     */
    public class MyBinder extends Binder {
        public FaceLedService getService() {
            return FaceLedService.this;
        }
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        connect();
        return START_NOT_STICKY;
    }

    /**
     * 连接服务器
     */
    private void connect() {
        if (!NettyClient.getInstance().getConnectStatus()) {
            if (es == null || es.isShutdown()) {
                es = Executors.newCachedThreadPool();
            }
            es.execute(new Runnable() {
                @Override
                public void run() {
                    NettyClient.getInstance().connect();//连接服务器
                }
            });
        }
    }

    /**
     * 连接成功后登录
     */
    private void login() {
        NettySendMsgModel model = new NettySendMsgModel(NettySendMsgModel.SendType.LOGIN);
        NettyClient.getInstance().sendMsgToServer(model, null);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        NettyClient.getInstance().init(this);
        mac = MacUtils.getMac();
        md5Mac = Md5Utils.getMD5(mac);
    }

    /**
     * 接收到tcp消息回调
     */
    @Override
    public void onMessageResponse(NettyReceiverModel model) {
        try {
            String str = new String(model.getData(), Charset.forName("UTF-8"));
            JSONObject jsonObject = new JSONObject(str);
            String serviceName = jsonObject.optString(NettyConstants.SERVICE_NAME);
            if (TextUtils.isEmpty(serviceName)) {
                return;
            }
            Logger.d("serviceName=" + serviceName + ",jsonObject=" + jsonObject.toString());
            String md5 = jsonObject.optString("md5");
            if (TextUtils.isEmpty(md5)) {
                return;
            }
            JSONObject jsonObject1 = new JSONObject(jsonObject.optString("data"));
            //md5加密校验
//            if (!md5.equals(Md5Utils.getMD5(serviceName + jsonObject1.toString() + md5Mac))) {
//                return;
//            }
            parseJson(serviceName, jsonObject1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 重启
     */
    private void reBoot(String uuid) {
        if (es == null || es.isShutdown()) {
            es = Executors.newCachedThreadPool();
        }
        final JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty(NettyConstants.SERVICE_NAME, NettyConstants.RE_START);
        jsonObject.addProperty("mac", mac);
        JsonObject jsonObject1 = new JsonObject();
        jsonObject1.addProperty("state", 1);
        jsonObject1.addProperty("uuid", uuid);
        jsonObject.add("data", jsonObject1);
        es.execute(new Runnable() {
            @Override
            public void run() {
                NettyClient.getInstance().sendMsgToServer(new NettySendMsgModel
                        (NettySendMsgModel.SendType.DATA, jsonObject.toString()), new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture channelFuture) throws Exception {
                        if (channelFuture.isSuccess()) {
                            NettyClient.getInstance().disconnect();
                            connect();
                        }
                    }
                });
            }
        });
    }

    private void parseJson(String serviceName, JSONObject jsonObject) {
        Logger.d("json-data=" + jsonObject.toString());
        //设置参数
        if (serviceName.equals(NettyConstants.SET_PAR)) {
            String uuid = jsonObject.optString("uuid");
            if (TextUtils.isEmpty(uuid)) {
                return;
            }
            String key = jsonObject.optString("key");
            if (TextUtils.isEmpty(key)) {
                setResult(NettyConstants.SET_PAR, new ResultModel("state", -1), new ResultModel("uuid", uuid));
                return;
            }
            String val = jsonObject.optString("value");
            if (TextUtils.isEmpty(val)) {
                setResult(NettyConstants.SET_PAR, new ResultModel("state", -1), new ResultModel("uuid", uuid));
                return;
            }
            switch (key) {
                case "loginId":
                    MyApp.getInstance().mDataManager.setLoginId(val);
                    setResult(NettyConstants.SET_PAR, new ResultModel("state", 1), new ResultModel("uuid", uuid));
                    break;
                case "loginPsw":
                    MyApp.getInstance().mDataManager.setLoginPassword(val);
                    setResult(NettyConstants.SET_PAR, new ResultModel("state", 1), new ResultModel("uuid", uuid));
                    break;
                default:
                    setResult(NettyConstants.SET_PAR, new ResultModel("state", -1), new ResultModel("uuid", uuid));
                    break;
            }
            return;
        }
        //重连平台
        //重启 即重新连接
        if (serviceName.equals(NettyConstants.RE_START)) {
            String uuid = jsonObject.optString("uuid");
            if (TextUtils.isEmpty(uuid)) {
                return;
            }
            reBoot(uuid);
            return;
        }
        //登录回复 发送心跳
        if (serviceName.equals(NettyConstants.LOGIN)) {
            int state = jsonObject.optInt("state");
            if (state == 1) {
                sendPulse();
            }
            return;
        }
        //下发或修改人脸
        if (serviceName.equals(NettyConstants.USER_ADD)) {
            Logger.d("下发或修改人脸");
            long faceID = jsonObject.optLong("faceId", -1);
            if (faceID < 0) {
                return;
            }
            String name = jsonObject.optString("name");
            if (TextUtils.isEmpty(name)) {
                return;
            }
            String img = jsonObject.optString("img");
            if (TextUtils.isEmpty(img)) {
                return;
            }
            String workerType = jsonObject.optString("workerType");
            if (TextUtils.isEmpty(workerType)) {
                return;
            }
            String admin = jsonObject.optString("admin");
            if (TextUtils.isEmpty(admin)) {
                return;
            }
            String teamName = jsonObject.optString("teamName");
            if (TextUtils.isEmpty(teamName)) {
                return;
            }
            String bodyTemp = jsonObject.optDouble("temperature") + "";
//            if (TextUtils.isEmpty(bodyTemp)) {
//                return;
//            }
//            Logger.d("bodyTemp: " + bodyTemp);
            String path = Base64Utils.base64ToFile(img,
                    (FileUtils.getFaceDirectory().getPath() + "/" + System.currentTimeMillis() + ".jpg"));
            if (TextUtils.isEmpty(path)) {
                return;
            }
            UserData userData = new UserData(faceID, name, path, workerType, admin, teamName, bodyTemp);
            boolean isSuccess = MyApp.getInstance().mDataManager.insertOrReplaceUserData(userData);
            if (isSuccess) {
                setResult(NettyConstants.USER_ADD, new ResultModel("faceId", faceID));
            }
            return;
        }
        //删除单个人脸
        if (serviceName.equals(NettyConstants.USER_DEL)) {
            long faceID = jsonObject.optLong("faceId", -1);
            if (faceID < 0) {
                return;
            }
            boolean isDeleteSuccess = MyApp.getInstance().mDataManager.deleteUserDataById(faceID);
            if (isDeleteSuccess) {
                setResult(NettyConstants.USER_DEL, new ResultModel("faceId", faceID));
            }
            return;
        }
        //删除全部人脸
        if (serviceName.equals(NettyConstants.USER_DEL_ALL)) {
            String uuid = jsonObject.optString("uuid");
            if (TextUtils.isEmpty(uuid)) {
                return;
            }
            if (MyApp.getInstance().mDataManager.deleteAllUserData()) {
                setResult(NettyConstants.USER_DEL_ALL, new ResultModel("uuid", uuid));
            }
            return;
        }
        //下发进出记录
        if (serviceName.equals(NettyConstants.INOUT_RECORD)) {
            Logger.d("下发进出记录");
            RecordData data = new Gson().fromJson(jsonObject.toString(), RecordData.class);
            if (data == null) {
                Logger.e("下发进出记录 ---data==null");
                return;
            }
            if (data.getFaceId() == null) {
                Logger.e("下发进出记录--faceId为空");
                return;
            }
            UserData userData = MyApp.getInstance().mDataManager.getUserDataById(data.getFaceId());
            if (userData == null) {
                setResult(NettyConstants.INOUT_RECORD, new ResultModel("faceId", data.getFaceId()));
                Logger.e("下发进出记录---userdata为空");
                return;
            }
            if (listener != null) {
                listener.onRecord(userData, data);
            }
            return;
        }
        //平台下发广告语
        if (serviceName.equals(NettyConstants.PUSH_AD)) {
            String uuid = jsonObject.optString("uuid");
            if (TextUtils.isEmpty(uuid)) {
                return;
            }
            String inOutAdv = jsonObject.optString("inOutAdv");
            String freeAdv = jsonObject.optString("freeAdv");
            MyApp.getInstance().mDataManager.setInOutAdv(inOutAdv);
            MyApp.getInstance().mDataManager.setFreeAdv(freeAdv);
            setResult(NettyConstants.PUSH_AD, new ResultModel("uuid", uuid));
            if (listener != null) {
                listener.onAdvChange(inOutAdv, freeAdv);
            }
            return;
        }
        //平台下发工地名
        if (serviceName.equals(NettyConstants.LED_SET_PAR)) {
            String key = jsonObject.optString("key");
            if (!key.equals(NettyConstants.SITE_NAME)) {
                return;
            }
            String name = jsonObject.optString("val");
            MyApp.getInstance().mDataManager.setSiteName(name);
            String uuid = jsonObject.optString("uuid");
            if (!TextUtils.isEmpty(uuid)) {
                setResult(NettyConstants.SITE_NAME, new ResultModel("uuid", uuid));
            }
            if (listener != null) {
                listener.onSiteNameChange(name);
            }
        }
    }

    private NettySendMsgModel pulseModel;

    /**
     * 心跳任务
     */
    private Runnable pulseRunnable = new Runnable() {
        @Override
        public void run() {
            NettyClient.getInstance().sendMsgToServer(pulseModel, null);
        }
    };

    /**
     * 发送心跳
     */

    private void sendPulse() {
        if (pulseEs == null || !pulseEs.isShutdown()) {
            pulseEs = Executors.newSingleThreadScheduledExecutor();
        }
        pulseModel = new NettySendMsgModel(NettySendMsgModel.SendType.HEART);
        pulseEs.scheduleAtFixedRate(pulseRunnable, 3, 40, TimeUnit.SECONDS);
    }

    /**
     * 结果统一回复
     */
    private void setResult(String serviceName, ResultModel... models) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty(NettyConstants.SERVICE_NAME, serviceName);
        jsonObject.addProperty("mac", mac);
        if (models != null && models.length > 0) {
            JsonObject jsonObject1 = new JsonObject();
            for (ResultModel model : models) {
                if (model.getVal() instanceof String) {
                    jsonObject1.addProperty(model.getKey(), (String) model.getVal());
                } else if (model.getVal() instanceof Boolean) {
                    jsonObject1.addProperty(model.getKey(), (Boolean) model.getVal());
                } else if (model.getVal() instanceof Character) {
                    jsonObject1.addProperty(model.getKey(), (Character) model.getVal());
                } else if (model.getVal() instanceof Number) {
                    jsonObject1.addProperty(model.getKey(), (Number) model.getVal());
                }
            }
            jsonObject.add("data", jsonObject1);
        }
        NettyClient.getInstance().sendMsgToServer(new NettySendMsgModel
                (NettySendMsgModel.SendType.DATA, jsonObject.toString()), null);
    }

    /**
     * tcp连接状态更改回调
     */
    @Override
    public void onServiceStatusConnectChanged(int statusCode) {
        if (statusCode == NettyListener.STATUS_CONNECT_SUCCESS) {
            login();
        } else {
            destroyThreadPool();
        }
    }

    /**
     * 销毁线程池 因为在异常离线后 该线程池还在继续运行 不仅浪费了资源 还做了无用功
     */
    private void destroyThreadPool() {
        if (pulseEs != null) {
            if (!pulseEs.isShutdown()) {
                try {
                    pulseEs.shutdown();
                    pulseEs = null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
